package com.newy.web.sys;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.newy.core.BaseController;
import com.newy.core.util.ReflectionUtils;
import com.newy.core.web.AppContext;
import com.newy.domain.sys.vo.ServerJvmDesc;
import com.newy.domain.sys.vo.ServerOsDesc;
import com.newy.domain.sys.vo.ServerPerf;
import com.newy.service.sys.MonitorService;
import com.newy.service.sys.UtilService;


/**
 * 工具性质功能的控制类。
 * 提供一些非业务性的功能，比如：获取枚举、管理hibernate二级缓存、获取服务器信息等
 * @author LinZongxue 2011-10-09
 *
 */
@Controller
@RequestMapping("sys/util")
public class UtilController extends  BaseController{
	@Resource private UtilService utilSvc;
	@Resource private MonitorService monitorSvc;
	
	/**
	 * 根据枚举类型的路径(除去com.newy.domain)，获取该类型的所有枚举。例如，获取菜单类型的枚举的url为：
	 * sys/getEnumItems.do?c=sys.Menu$MenuType<br/>
	 * 返回的格式为{name1: text1, name2:text2, ...}
	 * 另外，定义枚举类型时，都要求添加一个text属性。
	 * @param c 枚举类型的路径
	 */
	@RequestMapping("getEnumItems")@ResponseBody
	public Map<String, Object> getEnumItems(String c){
		try {
			Class<?> clazz = Class.forName(AppContext.BASE_PACKAGE + ".domain." + c);
			if (!clazz.isEnum()) throw new RuntimeException(c + "不是枚举类型");
			Map<String, Object> result = new LinkedHashMap<String, Object>(); //注意保持顺序
			for (Object e : clazz.getEnumConstants()){
				result.put( ((Enum<?>)e).name(), ReflectionUtils.invokeGetterMethod(e, "text"));
			}
			return result;
		} catch (ClassNotFoundException e) {
			List<String> tips = new ArrayList<String>();
			if (c.startsWith("com.")) tips.add("类型路径不要包括" + AppContext.BASE_PACKAGE + ".domain");
			if (!c.contains("$")) tips.add("类内部枚举的最后一个分隔符是$");
			throw new RuntimeException("找不到类型：" + c + (tips.isEmpty() ? "" : "，注意：" + StringUtils.join(tips, "，")));
		}catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 获取某个具有树形结构的实体的某个属性的路径，从根节点开始，以“/”为分隔符
	 * @param id 指定的实体ID
	 * @param a 要获取路径的属性名称
	 * @param p 指定父节点的属性名，默认为parentId
	 * @param c 实体类名，不包括com.newy.domain
	 * @return 由“/”连接的属性路径
	 */
	@RequestMapping("getEntityAttrPath") @ResponseBody
	public String getEntityAttrPath(Long id, String a, String p, String c){
		c = AppContext.BASE_PACKAGE + ".domain." + c;
		return utilSvc.getEntityAttrPath(id, a, p, c);
	}
	
	/**
	 * 获取Hibernate二级缓存中所有实体的相关信息，包括name、countInMemory、countOnDisk和sizeInMemory
	 */
	@RequestMapping("getAllEntitiesCacheInfo") @ResponseBody
	public List<Map<String,Object>> getAllEntitiesCacheInfo(){
		return utilSvc.getAllEntitiesCacheInfo();
	}

	@RequestMapping("removeEntityFromCache") @ResponseBody
	public boolean removeEntityFromCache(String entityName, Long id){
		return utilSvc.removeEntityFromCache(entityName, id);
	}
	
	@RequestMapping("removeEntityRegionFromCache") @ResponseBody
	public void removeEntityRegionFromCache(String entityName){
		utilSvc.removeEntityRegionFromCache(entityName);
	}
	
	@RequestMapping("removeAllEntitiesFromCache") @ResponseBody
	public void removeAllEntitiesFromCache(){
		utilSvc.removeAllEntitiesFromCache();
	}

	/**
	 * 获取服务器操作系统的一些描述信息
	 */
	@RequestMapping("getServerOsDesc") @ResponseBody
	public ServerOsDesc getServerOsDesc(){
		return monitorSvc.getServerOsDesc();
	}
	
	/**
	 * 获取服务JVM的一些描述信息
	 */
	@RequestMapping("getServerJvmDesc") @ResponseBody
	public ServerJvmDesc getServerJvmDesc(){
		return monitorSvc.getServerJvmDesc();
	}
	
	/**
	 * 获取服务器的一些描述信息，包括Java虚拟机和操作系统的描述信息。
	 */
	@RequestMapping("getServerPerfData") @ResponseBody
	public ServerPerf getServerPerfData(){
		return monitorSvc.getServerPerfData();
	}
}
